package cn.hengzhu.main_manager.web.xcx;

import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeoutException;
import javax.servlet.http.HttpServletRequest;

import cn.hengzhu.main_manager.repository.dao.*;
import cn.hengzhu.main_manager.repository.domain.*;
import cn.hengzhu.main_manager.repository.vo.ManageCaseBoxVO;
import cn.hengzhu.main_manager.service.ManageCaseTypePriceService;
import cn.hengzhu.main_manager.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import cn.hengzhu.main_manager.service.CustomersAmountService;
import cn.hengzhu.main_manager.service.ManageCaseBoxService;
import cn.hengzhu.main_manager.service.PayOrderService;
import cn.hengzhu.main_manager.utils.config.AllConst;
import cn.hengzhu.main_manager.utils.config.AppConfig;
import cn.hengzhu.main_manager.utils.config.xcx.WxConfig;

/**
 * @author 刘成
 * @since 2018年10月12日 微信小程序常规柜子项目
 */
@Controller
@RequestMapping("/wxCommonxcx")
public class WXXcxCommonContrller {

	private Logger log = Logger.getLogger(WXXcxCommonContrller.class);

	@Autowired
	private ManageCaseBoxService manageCaseBoxService;
	@Autowired
	private ManageCaseBoxMapper manageCaseBoxMapper;
	@Autowired
	private CustomersAmountMapper customersAmountMapper;
	@Autowired
	private ManageCaseMapper manageCaseMapper;
	@Autowired
	private ManageCaseTypeMapper manageCaseTypeMapper;
	@Autowired
	private PayOrderMapper payOrderMapper;
	@Autowired
	private PayOrderService payOrderService;
	@Autowired
	private SysConstMapper sysConstMapper;
	@Autowired
	CustomersAmountService customersAmountService;
	@Autowired
	MobileBindKeyMapper mobileBindKeyMapper;
	@Autowired
	ManageCaseTypePriceService manageCaseTypePriceService;
	@Autowired
	ManageCaseTypePriceMapper manageCaseTypePriceMapper;
	@Autowired
	AccessRecordMapper accessRecordMapper;

	/**
	 * 续时
	 * @param caseBox.id  主键
	 *        caseBox.userId 用户唯一标识
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/continued")
	public Map<String, Object> continued(ManageCaseBox caseBox) {
		Map<String,Object> map = manageCaseBoxService.continued(caseBox);
		return map;
	}


	/**
	 * 续时，微信小程序弹窗点击确定请求此接口 进行账户扣费续时
	 * payOrder.openId
	 * parOrder.boxId
	 */
	@ResponseBody
	@RequestMapping("/continuedUse")
	public Map<String, Object> continuedUse(ManageCaseBox caseBox) {
		Map<String, Object> map = manageCaseBoxService.continuedUse(caseBox);
		return map;
	}

	/**
	 * 租车
	 * 	目前会有三个参数：
	 * 		1. caseNo mac地址
	 * 		2. userId 用户唯一标识
	 * 		3. priceId 收费id
	 * 	扣费逻辑： 当用户账户里的余额大于等于要支付的的金额时 直接从余额扣款
	 * 			  如果余额小于要支付的金额 调用微信接口支付
	 */
	@ResponseBody
	@RequestMapping("/carrental")
	public Map<String, Object> carRental(ManageCaseBoxVO vo) {
		Map<String,Object> map = manageCaseBoxService.carRental(vo);
		return map;
	}

	/**
	 * @author 谭芸
	 * @since 2021年4月6日
	 * 结束使用 还车
	 * @param boxVO
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/endUse")
	public Map<String,Object> enduse(ManageCaseBox boxVO) {
		Map<String, Object> map = manageCaseBoxService.endUse(boxVO);
		return map;
	}

	/**
	 * 点击确定进行扣费开箱
	 * @param payOrder.openId
	 * @param payOrder.boxId 箱子id
	 * @param priceId  收费id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/chargesforunpacking")
	public Map<String,Object> chargesForUnpacking(PayOrder payOrder, String priceId) {
		Map<String,Object> map = manageCaseBoxService.chargesForUnpacking(payOrder, priceId);
		return map;
	}


	/**
	 * 续时使用 的微信支付回调
	 *  1.将订单状态修改为已支付
	 *  2.添加一条记录
	 *  3.修改箱子超时时长
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/continuedUseCallback")
	public String continuedUseCallback(HttpServletRequest request) {
		try {
			Map<String, String> map = getStringStringMap(request); // 将回调中的参数转为一个map

			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {
				log.info("支付成功：success");
				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");
				String nonce_str = map.get("attach");
//				String priceId = nonce_str.substring(nonce_str.indexOf("=")+1);

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) { // 查询到此订单
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					Integer totalFee = payOrder.getTotalFee();
					String amountY = AmountUtils.changeF2Y(totalFee + ""); // 分转为元 即将扣费的金额
					// 1. 设置此订单支付状态为已支付
					payOrder.setIsPay((byte) 1); //设置为已支付
					int returnEd = payOrderMapper.updateByPrimaryKey(payOrder);

					// 2. 设置箱子超时时间
					ManageCaseBoxExample manageCaseBoxExample = new ManageCaseBoxExample();
					manageCaseBoxExample.createCriteria().andIdEqualTo(boxId).andUseStatusEqualTo((byte) 1).andIsConnEqualTo((byte) 1);
					List<ManageCaseBox> manageCaseBoxes = manageCaseBoxMapper.selectByExample(manageCaseBoxExample);
					ManageCaseBox manageCaseBox = manageCaseBoxes.get(0);
					String caseTypePriceId = manageCaseBox.getCaseTypePriceId();
					ManageCaseTypePrice manageCaseTypePrice = manageCaseTypePriceMapper.selectByPrimaryKey(caseTypePriceId);
					String thePrice = manageCaseTypePrice.getThePrice();
					Integer theLenght = manageCaseTypePrice.getTheLenght();
					int period = totalFee % Double.valueOf(thePrice) > 0 ? totalFee / Integer.valueOf(thePrice) + 1 : totalFee / Integer.valueOf(thePrice);
					int delayedTime = period * theLenght; // 延时多久 单位分钟
					Date clearBoxTime = manageCaseBox.getClearBoxTime(); // 现在的到期时间

					Calendar cal = Calendar.getInstance();
					cal.setTime(clearBoxTime);
					cal.add(Calendar.MINUTE, delayedTime);
					if (clearBoxTime.getTime() < new Date().getTime()){
						manageCaseBox.setClearBoxTime(cal.getTime());
						manageCaseBoxMapper.updateByPrimaryKey(manageCaseBox);  // 修改超时时间
					}

					// 3.添加一条记录
					Date date = new Date();
					String amount = AmountUtils.changeF2Y(totalFee+"");
					AccessRecord accessRecord = new AccessRecord();
					accessRecord.setBoxId(manageCaseBox.getId());
					accessRecord.setCreateTime(date);
					accessRecord.setType(AllConst.ACCESS_RECORD_TYPE.CONTINUE_USE);  // 类型
					accessRecord.setSource(AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE);
					accessRecord.setUserId(openId);
					accessRecord.setCharge(new BigDecimal(amount));
					Date saveTime = manageCaseBox.getSaveTime();
					accessRecord.setUseTime(new Date().getTime() - saveTime.getTime()); // 使用时长
					accessRecord.setCreateDay(DateTimeHelper.formatDateTimetoString(date, "yyyy-MM-dd"));
					try {
						accessRecordMapper.insertSelective(accessRecord); // 开箱记录

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
					} catch (Exception e) {
						e.printStackTrace();
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}

	}

	/**
	 * 结束用车超时时的微信支付回调
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/overtimeChargeCallback")
	public String overtimeChargeCallback(HttpServletRequest request) {
		try {
			Map<String, String> map = getStringStringMap(request);

			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {
				log.info("支付成功：success");
				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");
				String nonce_str = map.get("attach");
				String priceId = nonce_str.substring(nonce_str.indexOf("=")+1);

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) { // 查询到此订单
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					Integer totalFee = payOrder.getTotalFee();
					String amountY = AmountUtils.changeF2Y(totalFee + ""); // 分转为元 即将扣费的金额
					// 设置此订单支付状态为已支付
					payOrder.setIsPay((byte) 1); //设置为已支付
					int returnEd = payOrderMapper.updateByPrimaryKey(payOrder);

					// 查询使用的储物箱
					ManageCaseBoxExample manageCaseBoxExample = new ManageCaseBoxExample();
					manageCaseBoxExample.createCriteria().andIdEqualTo(boxId).andUseStatusEqualTo((byte) 1).andIsConnEqualTo((byte) 1);
					List<ManageCaseBox> manageCaseBoxes = manageCaseBoxMapper.selectByExample(manageCaseBoxExample);
					ManageCaseBox manageCaseBox = manageCaseBoxes.get(0);

					try {
						// 开箱
						manageCaseBoxService.openBoxCommonByNewXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.REPAY_TYEP,
								AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE, AllConst.CASE_BOX_SAVE_SOURCE.WX_XCX_SAVE_SOURCE,
								0,amountY);

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						e.printStackTrace();
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}

	}

	/**
	 * 租车支付回调
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/cartFeeCallback")
	public String cartFeeCallback(HttpServletRequest request) {
		try {
			Map<String, String> map = getStringStringMap(request);

			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {
				log.info("支付成功：success");
				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");
				String nonce_str = map.get("attach");
				String priceId = nonce_str.substring(nonce_str.indexOf("=")+1);


				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) { // 查询到此订单
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					Integer totalFee = payOrder.getTotalFee();
					String amountY = AmountUtils.changeF2Y(totalFee + ""); // 分转为元 即将扣费的金额
					// 设置此订单支付状态为已支付
					payOrder.setIsPay((byte) 1); //设置为已支付
					int returnEd = payOrderMapper.updateByPrimaryKey(payOrder);

					// 查询使用的储物箱
					ManageCaseBoxExample manageCaseBoxExample = new ManageCaseBoxExample();
					manageCaseBoxExample.createCriteria().andIdEqualTo(boxId).andUseStatusEqualTo((byte) 0).andIsConnEqualTo((byte) 1);
					List<ManageCaseBox> manageCaseBoxes = manageCaseBoxMapper.selectByExample(manageCaseBoxExample);
					ManageCaseBox manageCaseBox = manageCaseBoxes.get(0);
					if (manageCaseBoxes == null || manageCaseBoxes.size() == 0){
						// 箱子已被占用, 重新选一个没有被使用的箱子
						List<ManageCaseBox> manageCaseBoxeList = manageCaseBoxService.availableCabinet(manageCaseBox.getCaseNo());
						if (manageCaseBoxeList == null || manageCaseBoxeList.size() == 0) throw new RuntimeException("没有可用的箱子");
						Random rand = new Random();
						manageCaseBox = manageCaseBoxeList.get(rand.nextInt(manageCaseBoxeList.size())); // 随机抽取一个可用的箱子
					}

					Integer totalMinute = this.overTime(priceId); // 超时时间
					try {
						// 开箱
						manageCaseBoxService.openBoxCommonByNewXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.BORROW_TYEP,
								AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE, AllConst.CASE_BOX_SAVE_SOURCE.WX_XCX_SAVE_SOURCE,
								totalMinute, (byte) 1, (byte) 2,amountY, priceId);

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						e.printStackTrace();
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}


	}



	/**
	 * @author liuCheng
	 * @since 2018年10月24日
	 * @param caseNo
	 * @param openId
	 * @param doorNum
	 * @return
	 * @throws Exception
	 *             密码开箱（存物） pagejump ---8 收费
	 * 
	 */
	@RequestMapping("/openbox")
	@ResponseBody
	public Map<String, Object> openbox(String caseNo, String openId, Integer doorNum, String password)
			throws Exception {
		log.info("caseNo:" + caseNo + " openId:" + openId + " doorNum:" + doorNum + " password:" + password);

		Map<String, Object> map = new HashMap<>();
		Date date = new Date();

		// 查询储物柜的基本信息
		ManageCaseExample manageCaseExample = new ManageCaseExample();
		manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(manageCaseExample);
		ManageCase manageCase = manageCaseList.get(0);

		// 查询是否在使用
		ManageCaseBoxExample manageCaseBoxExample = new ManageCaseBoxExample();
		manageCaseBoxExample.createCriteria().andCaseNoEqualTo(caseNo).andUserIdEqualTo(openId)
				.andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> manageCaseBoxList = manageCaseBoxMapper.selectByExample(manageCaseBoxExample); //查询此用户是否正在使用一个柜子中
		Integer typeId = manageCase.getTypeId(); // 柜子收费类型id

		if (null == typeId) {
			log.info("该门柜type为空！");
			map.put("pagejump", "500");
			map.put("message", "系统错误");
			return map;
		}

		Integer clearHour = manageCase.getClearHour(); // 储物超时时间 默认12小时
		ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId); // 查询出对应收费类型信息
		Byte payType = manageCaseType.getPayType(); // 收费类型 0 免费 1 计时 2 记次
		// 在使用
		if (!manageCaseBoxList.isEmpty()) {
			Integer doorNum2 = manageCaseBoxList.get(0).getDoorNum(); // 几号箱
			log.info("找到该门柜！");
			if (Byte.valueOf("0").equals(payType)) {
				log.info("该门柜免费！");
				map.put("pagejump", "0");
				map.put("message", "查询到你已经使用了储物柜的" + doorNum2 + "号箱，点击确定，即可开启箱门,谢谢您的支持！！!");
			} else {
				log.info("该门柜不免费！");
				map.put("pagejump", "0");
				map.put("message", "查询到你已经使用了储物柜的" + doorNum2 + "号箱，点击确定，我们会为你生成账单,谢谢您的支持！！!");
			}
			return map;
		}


		// 存物
		Byte isBindMobile = manageCaseType.getIsBindMobile();// 0.不需要绑定 1.需要
		if (Byte.valueOf("1").equals(isBindMobile)) {
			if (password == null || "".equals(password)) {  // 密码不能为空
				log.info("该手机未绑定，必须绑定！！！返回500");
				map.put("pagejump", "500");
				map.put("message", "密码不能为空！");
				return map;
			}
			// 获取手机号
			MobileBindKeyExample mbkExample = new MobileBindKeyExample();
			mbkExample.createCriteria().andOpenIdEqualTo(openId);
			List<MobileBindKey> mbkms = mobileBindKeyMapper.selectByExample(mbkExample); //	from mobile_bind_key where OPEN_ID =
			if (mbkms.isEmpty()) {
				map.put("pagejump", "500");
				map.put("message", "您未绑定手机！");
				return map;
			}
			// 密码改为手机号后四位加密码
			password += mbkms.get(0).getPhone().substring(7, 11);
		}

		// 未使用
		CustomersAmountExample customersAmountExample = new CustomersAmountExample();
		customersAmountExample.createCriteria().andOpenIdEqualTo(openId);
		List<CustomersAmount> customersAmountList = customersAmountMapper.selectByExample(customersAmountExample); // from customers_amount where OPEN_ID =
		if (customersAmountList.isEmpty()) {
			log.info("查询用户账户信息为空，即登陆失败！");
			map.put("pagejump", "500");
			map.put("message", "登陆失败,请重试");
			return map;
		}

		// 账户信息
		CustomersAmount customersAmount = customersAmountList.get(0);
		BigDecimal totalAmount = customersAmount.getTotalAmount(); // 余额
		if (totalAmount.doubleValue() < 0) {// 账户欠费
			log.info("该用户欠费！");
			map.put("pagejump", "3");
			map.put("message", "您已欠费，请充值后再使用!!!");
			return map;
		}

		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andCaseNoEqualTo(caseNo).andDoorNumEqualTo(doorNum).andIsDelEqualTo((byte) 0)
				.andIsConnEqualTo((byte) 1).andUseStatusEqualTo((byte) 0).andSwitchStatusEqualTo((byte) 1);
		List<ManageCaseBox> manageCaseBoxList2 = manageCaseBoxMapper.selectByExample(example); // 查询箱子是否被别人占用

		if (manageCaseBoxList2.isEmpty()) {// 已被使用
			log.info("该门柜被占用！");
			map.put("pagejump", "1");
			map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择!!!");
			return map;
		}

		ManageCaseBox manageCaseBox = manageCaseBoxList2.get(0); // 获取选择的箱子信息
		Integer boxId = manageCaseBox.getId();
		Byte payTime = manageCaseType.getPayTime(); // 收费时间（1.使用后收费  2.使用前收费）
		BigDecimal pledge = manageCaseType.getCashPledge();// 押金
		if (pledge.compareTo(BigDecimal.ZERO) == -1) {// 押金为负数,当作为0
			pledge = BigDecimal.ZERO;
		}

		if (Byte.valueOf("0").equals(payType)) {// 免费的直接开门
			log.info("该门柜免费，直接开门！");
			return openDoorBySaveAndNoPay(doorNum, caseNo, manageCaseBox, openId, clearHour, payTime, payType,
					password);
		}

		if (Byte.valueOf("2").equals(payTime)) {// 使用前收费
			log.info("该门柜需要收费，先占用！");
			// 使用前收费，首先需要先将此储物箱的状态修改为使用中
			ManageCaseBox manageCaseBox1 = new ManageCaseBox();
			manageCaseBox1.setUseStatus((byte) 1);
			manageCaseBox1.setSaveTime(date);
			manageCaseBox1.setUserId("123");
			manageCaseBox1.setVersion(manageCaseBox.getVersion() + 1);
			manageCaseBox1.setSaveSource(AllConst.CASE_BOX_SAVE_SOURCE.WX_XCX_SAVE_SOURCE);
			ManageCaseBoxExample manageCaseBoxExample1 = new ManageCaseBoxExample();
			manageCaseBoxExample1.createCriteria().andVersionEqualTo(manageCaseBox.getVersion())
					.andIdEqualTo(manageCaseBox.getId());
			int updateByExampleSelective = manageCaseBoxMapper.updateByExampleSelective(manageCaseBox1,
					manageCaseBoxExample1);
			if (updateByExampleSelective == 0) {// 占用不成功
				log.info("该门柜占用不成功！");
				map.put("pagejump", "1");
				map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择!!!");
				return map;
			}

			Byte isSize = manageCase.getIsSize(); // 是否区分大小柜
			Integer amount = 0; //
			if (Byte.valueOf("0").equals(isSize)) {// 不区分大中小柜
				String price = manageCaseType.getPrice();  // 金额
				Double valueOf = Double.valueOf(price) * 100;
				amount = valueOf.intValue();
			} else {// 区分大中小柜
				Byte size = manageCaseBox.getSize();
				String priceSize = manageCaseType.getPriceSize();
				List<String> asList = Arrays.asList(priceSize.split(","));

				if (Byte.valueOf("1").equals(size)) {
					String string = asList.get(0);
					Double valueOf = Double.valueOf(string) * 100;
					amount = valueOf.intValue();
				} else if (Byte.valueOf("2").equals(size)) {
					String string = asList.get(1);
					Double valueOf = Double.valueOf(string) * 100;
					amount = valueOf.intValue();
				} else if (Byte.valueOf("3").equals(size)) {
					String string = asList.get(2);
					Double valueOf = Double.valueOf(string) * 100;
					amount = valueOf.intValue();
				}
			}

			String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/prepayCallback";
			String place = manageCase.getPlace();
			String caseNoBuy = manageCase.getCaseNoBuy();
			String body = place + "--" + caseNoBuy + "--" + doorNum + "--存";
			// 产生随机数
			String nonce_str = DictionaryUtils.getRandomStr();
			String out_trade_no = "XF_wx_YF" + date.getTime() + nonce_str.substring(0, 2);
			map = prepayWeiXin(notify_url, body, nonce_str, out_trade_no, amount, pledge, openId, boxId, password);
			map.put("pagejump", "8");
			map.put("doorNum", doorNum);
			return map;
		}

		// 使用后收费【开门前需要支付押金】
		if (pledge.compareTo(BigDecimal.ZERO) == 1) {
			log.info("该门柜需要收费，先占用！");
			//使用前收费，首先需要先将此储物箱的状态修改为使用中
			ManageCaseBox manageCaseBox1 = new ManageCaseBox();
			manageCaseBox1.setUseStatus((byte) 1);
			manageCaseBox1.setSaveTime(date);
			manageCaseBox1.setUserId("123");
			manageCaseBox1.setVersion(manageCaseBox.getVersion() + 1);
			manageCaseBox1.setSaveSource(AllConst.CASE_BOX_SAVE_SOURCE.WX_XCX_SAVE_SOURCE);
			ManageCaseBoxExample manageCaseBoxExample1 = new ManageCaseBoxExample();
			manageCaseBoxExample1.createCriteria().andVersionEqualTo(manageCaseBox.getVersion()).andIdEqualTo(manageCaseBox.getId());
			int updateByExampleSelective = manageCaseBoxMapper.updateByExampleSelective(manageCaseBox1,manageCaseBoxExample1);
			if (updateByExampleSelective == 0) {// 占用不成功
				log.info("该门柜占用不成功！");
				map.put("pagejump", "1");
				map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择!!!");
				return map;
			}
			String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/prepayCallback";
			String place = manageCase.getPlace();
			String caseNoBuy = manageCase.getCaseNoBuy();
			String body = place + "--" + caseNoBuy + "--" + doorNum + "--存";
			// 产生随机数
			String nonce_str = DictionaryUtils.getRandomStr();
			String out_trade_no = "XF_wx_YF" + date.getTime() + nonce_str.substring(0, 2);
			map = prepayWeiXin(notify_url, body, nonce_str, out_trade_no, 0, pledge, openId, boxId, password);
			System.err.println(map.toString());
			map.put("pagejump", "8");
			map.put("doorNum", doorNum);
			return map;
		//使用后收费【开门前不需要支付押金】
		}else if(pledge.compareTo(BigDecimal.ZERO) < 1){
			log.info("使用后收费,押金小于0，直接开门！");
			return openDoorBySaveAndNoPay(doorNum, caseNo, manageCaseBox, openId, clearHour, payTime, payType, password);
		}
		
		log.info("----------------------");
		map.put("pagejump", "500");
		map.put("message", "系统错误");
		return map;
	}



	/**
	 * @author liuCheng
	 * @since 2018年10月23日
	 * @param openId
	 * @param caseNo 柜子mac地址
	 * @return
	 * @throws Exception
	 *             取物 code 101----直接展示 202-----付款
	 */
	@RequestMapping("/openMyBox")
	@ResponseBody
	public Map<String, Object> openMyBox(String openId, String caseNo) throws Exception {
		Date date = new Date();
		Map<String, Object> returnMap = new HashMap<>();

		int doorNum = 0;
		// 1.计算金额，生成账单
		// 1.1查询用户使用的储物柜的类别，，，是否区分大小柜
		ManageCaseExample caseExample = new ManageCaseExample();
		caseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(caseExample); // from manage_case where CASE_NO =

		if (!selectByExample2.isEmpty()) {
			ManageCase manageCase = selectByExample2.get(0);  // 柜子信息

			// 1.2查询到用户使用的箱子
			ManageCaseBoxExample example = new ManageCaseBoxExample();
			example.createCriteria().andCaseNoEqualTo(caseNo).andIsDelEqualTo((byte) 0).andUserIdEqualTo(openId)
					.andUseStatusEqualTo((byte) 1);
			// from manage_case_box where CASE_NO = caseNo and IS_DEL = 0 and USER_ID = openId and USE_STATUS = 1
			List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {
				ManageCaseBox manageCaseBox = selectByExample.get(0); // 获取到当前用户使用的柜子下的箱子信息
				Integer boxId = manageCaseBox.getId();
				Integer typeId = manageCase.getTypeId(); // 收费类型id
				doorNum = manageCaseBox.getDoorNum(); // 几号门
				ManageCaseType selectByPrimaryKey = manageCaseTypeMapper.selectByPrimaryKey(typeId); // 收费信息

				double aliCharge = CustomersAmountCount.getAliCharge(manageCaseBox, manageCase, selectByPrimaryKey); // 会返回支付的费用
				Double amountdouble = aliCharge * 100;
				Integer amount = amountdouble.intValue();
				log.info("需要支付的钱为：" + amount);
				BigDecimal pledge = BigDecimal.ZERO;// 初始化为0 押金 单位分
				CustomersAmountExample customersAmountExample = new CustomersAmountExample();
				customersAmountExample.createCriteria().andOpenIdEqualTo(openId);
				List<CustomersAmount> list = customersAmountMapper.selectByExample(customersAmountExample); //查询用户对应的账户信息
				if (!list.isEmpty()) {
					CustomersAmount ca = list.get(0);
					if (Byte.valueOf("1").equals(ca.getIsPay())) {// 已经缴纳押金
						pledge = ca.getAssureAmount().multiply(new BigDecimal("100"));// 获取押金单位元，乘100转为分
					}
				}

				if (amount == 0) {
					log.info("不需要额外从押金中扣费。。。。");
					return openDoorNoPay(doorNum, date, caseNo, openId, manageCaseBox); // 开门
				}
				amount = pledge.subtract(new BigDecimal(amount + "")).intValue();//单位分   押金减去 费用
				log.info("押金减去使用金额为："+amount);

				BigDecimal cost = BigDecimal.ZERO;
				//判断押金是否为0，0则不需要从押金扣除，也就不需要将扣除的押金写入账单
				if(pledge.compareTo(BigDecimal.ZERO) == 1){//大于0，有押金
					//判断费用是否大于押金,大于押金则:写入账单值取押金值,超出部分金额会从新支付并生成账单
					cost = new BigDecimal(amountdouble); // 费用
					if(cost.compareTo(pledge) == 1){cost = pledge;}  //a>b 1  a=b 0
					cost = cost.divide(new BigDecimal(100));//单位转为元
				}
				// 金额计算
				// 如果amount>0:退回该金额，清空押金
				// 如果amount=0:清空押金
				// 如果amount<0:需要支付，支付成功，清空押金 费用大于押金
				if (amount < 0) {
					// 需要支付，支付成功，清空押金
					log.info("/openMyBox押金扣完还需要支付！");
					String place = manageCase.getPlace(); //存储柜位置
					String caseNoBuy = manageCase.getCaseNoBuy(); //  商家自己所输入的编号
					String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/payCallback"; // 回调
					String body = place + "--" + caseNoBuy + "--" + doorNum + "--取";
					String nonce_str = DictionaryUtils.getRandomStr(); // 随机字符串
					String out_trade_no = "XF_wx" + date.getTime() + nonce_str.substring(0, 2);

					returnMap = payWeiXin(notify_url, body, nonce_str, out_trade_no, amount, openId, boxId);// 微信这里为分 会调用微信支付接口进行支付
					returnMap.put("doorNum", doorNum);
					returnMap.put("code", "202");
					return returnMap;
				} else if (amount > 0) {
					// backPay(openId, pledge);
					log.info("/openMyBox押金未扣完需要退押金！ ");
					double amountDouble =  Double.parseDouble(String.valueOf(amount));
					customersAmountService.setPledge(openId, new BigDecimal((amountDouble / 100) + ""));
					return openDoorNeedPay(openId, manageCaseBox,cost);
				} else {
					// 清空押金,直接开门
					log.info("/openMyBox不需要退押金，直接清除！");
					customersAmountService.clearPledge(openId);
					return openDoorNeedPay(openId, manageCaseBox,cost);
				}
				
			}
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月20日 下午4:01:12
	 * @param openId
	 * @param caseNo
	 * @return
	 * @throws Exception
	 *             中途取件
	 */
	@RequestMapping("/openMyBoxMidWay")
	@ResponseBody
	public Map<String, Object> openMyBoxMidWay(String openId, String caseNo) throws Exception {
		Date date = new Date();
		Map<String, Object> returnMap = new HashMap<>();
		int doorNum = 0;
		// 1.计算金额，生成账单
		// 1.1查询用户使用的储物柜的类别，，，是否区分大小柜
		ManageCaseExample caseExample = new ManageCaseExample();
		caseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(caseExample);

		if (!selectByExample2.isEmpty()) {
			ManageCase manageCase = selectByExample2.get(0);

			// 1.2查询到用户使用的箱子
			ManageCaseBoxExample example = new ManageCaseBoxExample();
			example.createCriteria().andCaseNoEqualTo(caseNo).andIsDelEqualTo((byte) 0).andUserIdEqualTo(openId)
					.andUseStatusEqualTo((byte) 1);
			List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {

				ManageCaseBox manageCaseBox = selectByExample.get(0);
				Integer boxId = manageCaseBox.getId();
				Integer typeId = manageCase.getTypeId();
				doorNum = manageCaseBox.getDoorNum();
				// 中途取件是否重计费
				if (manageCase != null) {
					Integer caseType = manageCase.getTypeId();
					ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(caseType);
					if (manageCaseType != null && Byte.valueOf("0").equals(manageCaseType.getIsHalfwayRestart())) {
						// 不需要重新计费
						returnMap = openDoorMidWayNoPay(doorNum, date, caseNo, openId, manageCaseBox);
						return returnMap;
					}
				}
				ManageCaseType selectByPrimaryKey = manageCaseTypeMapper.selectByPrimaryKey(typeId);

				double aliCharge = CustomersAmountCount.getMidWayAliCharge(manageCaseBox, manageCase,
						selectByPrimaryKey);
				Double amountdouble = aliCharge * 100;
				Integer amount = amountdouble.intValue();
				// 金额计算
				if (amount > 0) {
					String place = manageCase.getPlace();
					String caseNoBuy = manageCase.getCaseNoBuy();
					String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/payMidWayCallback";
					String body = place + "--" + caseNoBuy + "--" + doorNum + "--中途取件";
					String nonce_str = DictionaryUtils.getRandomStr();
					String out_trade_no = "XF_wx_zt" + date.getTime() + nonce_str.substring(0, 2);
					returnMap = payWeiXin(notify_url, body, nonce_str, out_trade_no, amount, openId, boxId);
					returnMap.put("doorNum", doorNum);
					returnMap.put("code", "202");
				} else {
					returnMap = openDoorMidWayNoPay(doorNum, date, caseNo, openId, manageCaseBox);
					return returnMap;
				}
			}
		}

		return returnMap;

	}

	/**
	 * @author liuCheng
	 * @since 2018年12月29日 下午5:34:12
	 * @param boxId
	 * @return
	 * @throws Exception
	 * 用户自己清除(与取物相同，唯一的区别是清除不打开柜门)
	 */
	@RequestMapping("/clearByOneself")
	@ResponseBody
	public Map<String, Object> clearByOneself(Integer boxId, String openId) throws Exception {
		Date date = new Date();
		Map<String, Object> map = new HashMap<>();
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andIdEqualTo(boxId).andUserIdEqualTo(openId).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (selectByExample.isEmpty()) {
			map.put("code", "401");// 没有此储物柜
			return map;
		}
		try {
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			String caseNo = manageCaseBox.getCaseNo();
			ManageCaseExample caseExample = new ManageCaseExample();
			caseExample.createCriteria().andCaseNoEqualTo(caseNo);
			List<ManageCase> caseList = manageCaseMapper.selectByExample(caseExample);
			ManageCase manageCase = caseList.get(0);
			Integer doorNum = manageCaseBox.getDoorNum();
			Integer typeId = manageCase.getTypeId();
			ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
			Byte source = AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE;
			Byte type = AllConst.ACCESS_RECORD_TYPE.CLEAR_BY_OWN;
			// 计算金额
			double aliCharge = CustomersAmountCount.getAliCharge(manageCaseBox, manageCase, manageCaseType);
			Double amountdouble = aliCharge * 100;
			Integer amount = amountdouble.intValue();
			BigDecimal pledge = BigDecimal.ZERO;// 初始化为0
			CustomersAmountExample customersAmountExample = new CustomersAmountExample();
			customersAmountExample.createCriteria().andOpenIdEqualTo(openId);
			List<CustomersAmount> list = customersAmountMapper.selectByExample(customersAmountExample);
			if (!list.isEmpty()) {
				CustomersAmount ca = list.get(0);
				if (Byte.valueOf("1").equals(ca.getIsPay())) {// 已经缴纳押金
					pledge = ca.getAssureAmount().multiply(new BigDecimal("100"));// 获取押金单位元，乘100转为分
				}
			}
			if (amount == 0) {
				log.info("不需要额外从押金中扣费。。。。");
				manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type);
				map.put("code", "200");
				return map;
			}
			amount = pledge.subtract(new BigDecimal(amount + "")).intValue();
			
			BigDecimal cost = BigDecimal.ZERO;
			//判断押金是否为0，0则不需要从押金扣除，也就不需要将扣除的押金写入账单
			if(pledge.compareTo(BigDecimal.ZERO) == 1){//大于0，有押金
				//判断费用是否大于押金,大于押金则:写入账单值取押金值,超出部分金额会从新支付并生成账单
				cost = new BigDecimal(amountdouble);
				if(cost.compareTo(pledge) == 1){cost = pledge;}
				cost = cost.divide(new BigDecimal(100));//单位转为元
			}
			// 金额计算
			// 如果amount>0:退回该金额，清空押金
			// 如果amount=0:清空押金
			// 如果amount<0:需要支付，支付成功，清空押金
			if (amount < 0) {
				// 需要支付，支付成功，清空押金
				String place = manageCase.getPlace();
				String caseNoBuy = manageCase.getCaseNoBuy();
				String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/clearPayCallback";
				String body = place + "--" + caseNoBuy + "--" + doorNum + "--清除";
				String nonce_str = DictionaryUtils.getRandomStr();
				String out_trade_no = "XF_wx" + date.getTime() + nonce_str.substring(0, 2);
				map = payWeiXin(notify_url, body, nonce_str, out_trade_no, Math.abs(amount), openId, boxId);
				map.put("code", 300);
				return map;
			} else if (amount > 0) {
				// 退还押金
				// backPay(openId, pledge);
				manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type, cost);
				map.put("code", "200");
				return map;
			}
			// 清空押金,直接开门
			manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type, cost);
			customersAmountService.clearPledge(openId);
			map.put("code", "200");
			return map;
		} catch (Exception e) {
			map.put("code", "500");// 清除失败请重试
			return map;
		}
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月3日 上午9:47:16
	 * @param boxId
	 * @param openId
	 * @return
	 * @throws Exception
	 *             继续使用
	 */
	@RequestMapping("/continueUsing")
	@ResponseBody
	public Map<String, Object> continueUsing(Integer boxId, String openId) throws Exception {
		Map<String, Object> map = new HashMap<>();
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andIdEqualTo(boxId).andUserIdEqualTo(openId).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (!selectByExample.isEmpty()) {
			Date date = new Date();
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			Integer doorNum = manageCaseBox.getDoorNum();
			String caseNo = manageCaseBox.getCaseNo();
			ManageCaseExample caseExample = new ManageCaseExample();
			caseExample.createCriteria().andCaseNoEqualTo(caseNo);
			List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(caseExample);
			ManageCase manageCase = manageCaseList.get(0);
			Integer typeId = manageCase.getTypeId();
			ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
			Byte payType = manageCaseType.getPayType();
			Integer amount = 0;
			// 查询使用费用
			// 插入继续使用的记录信息
			// 修改储物柜的使用时间、结束时间、
			if (Byte.valueOf("0").equals(payType)) {// 免费的若需要继续使用，需支付一定的费用
				SysConstExample sysExample = new SysConstExample();
				sysExample.createCriteria().andNameEqualTo(AppConfig.FREE_TIMEOUT);
				List<SysConst> sysConst = sysConstMapper.selectByExample(sysExample);
				String value = sysConst.get(0).getValue();
				Double a = Double.valueOf(value) * 100;
				amount = a.intValue();
			} else {// 非免费的支付相应的费用---与中途取物计算方式一样
				double aliCharge = CustomersAmountCount.getMidWayAliCharge(manageCaseBox, manageCase, manageCaseType);
				Double amountdouble = aliCharge * 100;
				amount = amountdouble.intValue();
			}
			if (amount > 0) {
				String notify_url = WxConfig.DOMAIN_URL + "/wxCommonxcx/continuePayCallback";
				String place = manageCase.getPlace();
				String caseNoBuy = manageCase.getCaseNoBuy();
				String body = place + "--" + caseNoBuy + "--" + doorNum + "--续费";
				// 产生随机数
				String nonce_str = DictionaryUtils.getRandomStr();
				String out_trade_no = "XF_wx_con" + date.getTime() + nonce_str.substring(0, 2);
				// 收费
				map = continueUsePayWeiXin(notify_url, body, nonce_str, out_trade_no, amount, openId, boxId);
				if (Byte.valueOf("0").equals(payType)) {
					map.put("code", "889");// 免费的支付
				} else {
					map.put("code", "888");// 支付
				}
			} else {
				map.put("message", "系统错误，暂时不能续费");// 免费的支付
				map.put("code", "444");// 无需现在续费
			}
		} else {
			map.put("message", "系统错误");// 免费的支付
			map.put("code", "401");// 没有使用此储物柜
		}
		return map;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月21日 上午9:32:30
	 * @param request
	 * @return 中途取物的支付成功后的逻辑----异步接口
	 */
	@RequestMapping("/payMidWayCallback")
	@ResponseBody
	public String payMidWayCallback(HttpServletRequest request) {
		String inputLine = "";
		String notityXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			// 关闭流
			request.getReader().close();
			// 解析成Map
			InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
			InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
			Map<String, String> map = XmlPullUtil.parse(isReader2);
			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {

				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) {
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					// 查询使用的储物箱
					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
					String caseNo = manageCaseBox.getCaseNo();

					try {
						manageCaseBoxService.payMidWayCommonCaseWXFinish(map, payOrder, manageCaseBox);
						// customersAmountService.clearPledge(openId);
						// 1.开门
						Connection connection = ConnectionUtils.getConnection();
						Channel channel = connection.createChannel();
						Map<String, Object> sendMap = new HashMap<>();
						sendMap.put("door", manageCaseBox.getDoorNum());
						sendMap.put("timestamp", new Date().getTime());
						ObjectMapper mapper = new ObjectMapper();
						Map<String, Object> args = new HashMap<String, Object>();
						args.put("x-message-ttl", 40000);
						channel.queueDeclare(caseNo, true, false, false, args);
						String writeValueAsString = mapper.writeValueAsString(sendMap);
						channel.basicPublish("", caseNo, null, writeValueAsString.getBytes());
						channel.close();
						connection.close();

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月2日 上午10:00:55
	 * @param caseNo
	 * @return
	 * @throws Exception
	 *             前端获取二维码地址
	 */
	@RequestMapping("/getQrUrl")
	@ResponseBody
	public Map<String, String> getQrUrl(String caseNo) throws Exception {
		Map<String, String> map = new HashMap<>();
		ManageCaseExample example = new ManageCaseExample();
		example.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> selectByExample = manageCaseMapper.selectByExample(example);
		if (!selectByExample.isEmpty()) {
			String qrUrl = selectByExample.get(0).getQrUrl();
			map.put("url", qrUrl);

			return map;
		} else {
			return map;

		}
	}




	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @param request
	 *            通知地址 回调服务器 支付结果(清除时需要支付后的回调)
	 * 
	 */
	@RequestMapping("/clearPayCallback")
	@ResponseBody
	public String clearPayCallback(HttpServletRequest request) {
		String inputLine = "";
		String notityXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			// 关闭流
			request.getReader().close();
			// 解析成Map

			InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
			InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
			Map<String, String> map = XmlPullUtil.parse(isReader2);
			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {

				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) {
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					// 查询使用的储物箱
					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
					String caseNo = manageCaseBox.getCaseNo();

					Date date = new Date();
					Long time = 0l;
					Date saveTime = manageCaseBox.getSaveTime();
					time = date.getTime() - saveTime.getTime();

					try {
						ManageCaseExample caseExample = new ManageCaseExample();
						caseExample.createCriteria().andCaseNoEqualTo(caseNo);
						List<ManageCase> caseList = manageCaseMapper.selectByExample(caseExample);
						ManageCase manageCase = caseList.get(0);
						Integer typeId = manageCase.getTypeId();
						ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
						Byte source = AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE;
						Byte type = AllConst.ACCESS_RECORD_TYPE.CLEAR_BY_OWN;
						manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type);
						manageCaseBoxService.clearPayFinishByAli(payOrder, manageCaseBox, manageCase, time);
						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}
	}

	/**
	 * @author 刘成
	 * @since 2018年8月10日
	 * @param request
	 *            通知地址 回调服务器 支付结果(这个回调 如果不返回给微信服务器 是否成功回调标示 则会一直回调8次 一直到返回成功标示位置)
	 * 
	 */
	@RequestMapping("/payCallback")
	@ResponseBody
	public String payCallback(HttpServletRequest request) {
		String inputLine = "";
		String notityXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			// 关闭流
			request.getReader().close();
			// 解析成Map
			InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
			InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
			Map<String, String> map = XmlPullUtil.parse(isReader2); // 解析成map

			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {

				String outTradeNo = map.get("out_trade_no"); // 交易编号
				String openId = map.get("openid"); // 用户唯一标识

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example); //from pay_order where OPEN_ID = and  IS_PAY = 0 and OUT_TRADE_NO = outTradeNo
				if (!payOrderList.isEmpty()) { // 有这个订单
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId(); // 箱子id
					// 查询使用的储物箱
					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId); // from manage_case_box
					String caseNo = manageCaseBox.getCaseNo(); // 储物柜的MAC

					try {

						manageCaseBoxService.payCommonCaseWXFinish(map, payOrder, manageCaseBox); // 执行相关操作。例如 修改储物柜下的箱子状态 修改支付订单状态 插入取物记录 公司账户加钱
						customersAmountService.clearPledge(payOrder.getOpenId()); // 清空押金

						// 1.开门
						Connection connection = ConnectionUtils.getConnection();
						Channel channel = connection.createChannel();
						Map<String, Object> sendMap = new HashMap<>();
						sendMap.put("door", manageCaseBox.getDoorNum());
						sendMap.put("timestamp", new Date().getTime());
						ObjectMapper mapper = new ObjectMapper();
						Map<String, Object> args = new HashMap<String, Object>();
						args.put("x-message-ttl", 40000);
						channel.queueDeclare(caseNo, true, false, false, args);
						String writeValueAsString = mapper.writeValueAsString(sendMap);
						channel.basicPublish("", caseNo, null, writeValueAsString.getBytes());
						channel.close();
						connection.close();

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月5日 下午5:34:51
	 * @param request
	 * @return 预付款成功后的回调接口
	 */
	@RequestMapping("/prepayCallback")
	@ResponseBody
	public String prepayCallback(HttpServletRequest request) {
		log.info("微信预付成功后回调！");
		String inputLine = "";
		String notityXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			// 关闭流
			request.getReader().close();
			// 解析成Map

			InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
			InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
			Map<String, String> map = XmlPullUtil.parse(isReader2);
			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {
				log.info("支付成功：success");
				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) {
					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					log.info("已找到订单。。。。。boxId：" + boxId);
					// 查询使用的储物箱
					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);

					try {
						log.info("调用支付后逻辑。。。。。");
						manageCaseBoxService.prepayCommonCaseWXFinish(map, payOrder, manageCaseBox);

						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						e.printStackTrace();
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月3日 上午11:57:51
	 * @param request
	 * @return 续费成功后
	 */
	@RequestMapping("/continuePayCallback")
	@ResponseBody
	public String continuePayCallback(HttpServletRequest request) {
		String inputLine = "";
		String notityXml = "";
		try {
			while ((inputLine = request.getReader().readLine()) != null) {
				notityXml += inputLine;
			}
			// 关闭流
			request.getReader().close();
			// 解析成Map

			InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
			InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
			Map<String, String> map = XmlPullUtil.parse(isReader2);
			// 判断 支付是否成功
			if ("SUCCESS".equals(map.get("result_code"))) {

				String outTradeNo = map.get("out_trade_no");
				String openId = map.get("openid");

				// 首先要查询到订单记录
				PayOrderExample example = new PayOrderExample();
				example.createCriteria().andOpenIdEqualTo(openId).andIsPayEqualTo((byte) 0)
						.andOutTradeNoEqualTo(outTradeNo);
				List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
				if (!payOrderList.isEmpty()) {
					// 金额
					String totalFee = map.get("total_fee");
					double valueOf = Double.valueOf(totalFee);
					String transactionId = map.get("transaction_id");
					BigDecimal amount = new BigDecimal(valueOf).divide(new BigDecimal(100), 3,
							BigDecimal.ROUND_HALF_UP);

					PayOrder payOrder = payOrderList.get(0);
					Integer boxId = payOrder.getBoxId();
					// 查询使用的储物箱
					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
					Byte source = AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE;

					try {
						manageCaseBoxService.continueCommonCaseFinish(transactionId, amount, payOrder, manageCaseBox,
								source);
						System.out.println("OK");
						return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

					} catch (Exception e) {
						System.out.println("ERROR");
						return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
					}

				} else {
					return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
				}

			} else {
				return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
			}

		} catch (Exception e) {
			return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
		}
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月21日 上午10:52:51
	 * @param doorNum
	 * @param date
	 * @param caseNo
	 * @param openId
	 * @param manageCaseBox
	 * @return 中途取件不用支付的逻辑
	 */
	private Map<String, Object> openDoorMidWayNoPay(int doorNum, Date date, String caseNo, String openId,
			ManageCaseBox manageCaseBox) {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMidWayMyCommonBoxByXcx(manageCaseBox, openId,
					AllConst.ACCESS_RECORD_TYPE.MIDWAY_GET_TYPE, AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE);
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "已为您开启" + doorNum + "号箱门，还可继续使用！");
			return returnMap;

		} catch (Exception e) {
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}

	/**
	 * @author liuCheng
	 * @since 2018年10月24日 下午3:11:15
	 * @param urls
	 * @param param
	 * @return 发送http请求
	 */
	public String getRemotePortData(String urls, String param) {
		try {
			URL url = new URL(urls);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置连接超时时间
			conn.setConnectTimeout(30000);
			// 设置读取超时时间
			conn.setReadTimeout(30000);
			conn.setRequestMethod("POST");
			if (StringUtils.isNotBlank(param)) {
				conn.setRequestProperty("Origin", "https://sirius.searates.com");// 主要参数
				// conn.setRequestProperty("Referer",
				// "https://sirius.searates.com/cn/port?A=ChIJP1j2OhRahjURNsllbOuKc3Y&D=567&G=16959&shipment=1&container=20st&weight=1&product=0&request=&weightcargo=1&");
				conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");// 主要参数
			}
			// 需要输出
			conn.setDoInput(true);
			// 需要输入
			conn.setDoOutput(true);
			// 设置是否使用缓存
			conn.setUseCaches(false);
			// 设置请求属性
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			conn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
			conn.setRequestProperty("Charset", "UTF-8");

			if (StringUtils.isNotBlank(param)) {
				// 建立输入流，向指向的URL传入参数
				DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
				dos.writeBytes(param);
				dos.flush();
				dos.close();
			}
			// 输出返回结果
			InputStream input = conn.getInputStream();
			int resLen = 0;
			byte[] res = new byte[1024];
			StringBuilder sb = new StringBuilder();
			while ((resLen = input.read(res)) != -1) {
				sb.append(new String(res, 0, resLen));
			}
			return sb.toString();
		} catch (MalformedURLException e) {
		} catch (IOException e) {
		}
		return "";
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月5日 下午2:04:01
	 * @param notify_url 回调url
	 * @param body 内容
	 * @param nonce_str 随机字符串
	 * @param boxId  箱子id
	 * @param openId 用户唯一标识
	 * @param amount 费用
	 * @param out_trade_no 交易编号
	 *            微信支付的统一生成订单（普通支付）
	 * @throws UnsupportedEncodingException
	 */
	private Map<String, Object>  payWeiXin(String notify_url, String body, String nonce_str, String out_trade_no,
			Integer amount, String openId, Integer boxId) throws UnsupportedEncodingException {
		amount = Math.abs(amount);// 取绝对值
		log.info("微信支付的统一生成订单:" + amount);
		Calendar calendar = Calendar.getInstance(); // 获得当前年月日
		calendar.add(Calendar.MINUTE, 2); // 获取两分钟之后的时间
		Date time = calendar.getTime();
		String time_expire = DateTimeHelper.formatDateTimetoString(time, "yyyyMMddHHmmss"); // 格式化时间

		Date date = new Date();
		Map<String, Object> map = new HashMap<>();
		String MCHID = WxConfig.MCH_ID; // 商户号
		String KEY = WxConfig.KEY; // 微信支付的商户密钥
		String appid = WxConfig.APPID; //小程序appID

		Map<String, String> payMap = WxPayBeforUtil.getPayMap(appid, MCHID, nonce_str, body, out_trade_no, amount,
				openId, notify_url, time_expire); // 转为一个map

		String stringA = DictionaryUtils.formatUrlMap(payMap, false, false); // 转成url
		String stringSignTemp = stringA + "&key=" + KEY;
		String sign = Md5Util.wxXcxHash(stringSignTemp).toUpperCase(); // 加密并转为大写

		// 将参数 编写XML格式
		StringBuffer paramBuffer = WxPayBeforUtil.getPayXml(appid, MCHID, nonce_str, body, out_trade_no, amount, openId,
				notify_url, time_expire, sign);

		// 	WxConfig.URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		String remotePortData = getRemotePortData(WxConfig.URL,
				new String(paramBuffer.toString().getBytes(), "ISO8859-1")); // 发送请求

		InputStream is = new ByteArrayInputStream(remotePortData.getBytes());
		InputStreamReader isReader = new InputStreamReader(is, "utf-8");
		Map<String, String> map1 = XmlPullUtil.parse(isReader); // 将返回值解析为map

		// 拿到接口返回值，插入记录
		String prepay_id = map1.get("prepay_id");
		// 请求订单号成功
		if (StringUtils.isNotBlank(prepay_id)) {
			log.info("请求订单号成功");
			// openId 交易编号 交易金额 箱子id 预付款id
			payOrderService.creatPayWx(openId, out_trade_no, amount, boxId, prepay_id); // 记录到pay_order中

			long seconds = date.getTime();
			Map<String, String> paySignMap = new HashMap<>();
			paySignMap.put("appId", appid);
			paySignMap.put("timeStamp", String.valueOf(seconds));
			paySignMap.put("nonceStr", nonce_str);
			paySignMap.put("package", "prepay_id=" + prepay_id);
			paySignMap.put("signType", "MD5");
			String stringPay = DictionaryUtils.formatUrlMap(paySignMap, false, false); // 生成url
			String paySign = WXMD5Util.MD5Encode(stringPay + "&key=" + KEY).toUpperCase(); //加密且转为大写

			map.put("timeStamp", String.valueOf(seconds));
			map.put("nonceStr", nonce_str);
			map.put("package", "prepay_id=" + prepay_id);
			map.put("signType", "MD5");
			map.put("paySign", paySign);
			map.put("outTradeNo", out_trade_no);
		}
		return map;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月5日 下午5:38:31
	 * @param notify_url
	 * @param body
	 * @param nonce_str
	 * @param out_trade_no
	 * @param amount
	 * @param pledge
	 *            押金
	 * @param openId
	 * @param boxId
	 * @param password
	 * @return
	 * @throws UnsupportedEncodingException
	 *             预付的统一订单生成（提前付款开箱的订单生成）
	 */
	public Map<String, Object> prepayWeiXin(String notify_url, String body, String nonce_str, String out_trade_no,
			Integer amount, BigDecimal pledge, String openId, Integer boxId, String password)
			throws UnsupportedEncodingException {

		// log.info("发送预付订单！amount:" + amount + " pledge:" + pledge);
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, 2);
		Date time = calendar.getTime();
		String time_expire = DateTimeHelper.formatDateTimetoString(time, "yyyyMMddHHmmss");
		BigDecimal cashPledge = pledge.multiply(new BigDecimal("100"));// 把押金转为分
		Date date = new Date();
		Map<String, Object> map = new HashMap<>();
		String MCHID = WxConfig.MCH_ID;
		String KEY = WxConfig.KEY;
		String appid = WxConfig.APPID;
		Map<String, String> payMap = WxPayBeforUtil.getPayMap(appid, MCHID, nonce_str, body, out_trade_no,
				amount + cashPledge.intValue(), openId, notify_url, time_expire);
		String stringA = DictionaryUtils.formatUrlMap(payMap, false, false);
		String stringSignTemp = stringA + "&key=" + KEY;
		String sign = Md5Util.wxXcxHash(stringSignTemp).toUpperCase();

		// 将参数 编写XML格式
		StringBuffer paramBuffer = WxPayBeforUtil.getPayXml(appid, MCHID, nonce_str, body, out_trade_no,
				amount + cashPledge.intValue(), openId, notify_url, time_expire, sign);
		String remotePortData = getRemotePortData(WxConfig.URL,
				new String(paramBuffer.toString().getBytes(), "ISO8859-1"));

		InputStream is = new ByteArrayInputStream(remotePortData.getBytes());
		InputStreamReader isReader = new InputStreamReader(is, "utf-8");
		Map<String, String> map1 = XmlPullUtil.parse(isReader);

		// 拿到接口返回值，插入记录
		String prepay_id = map1.get("prepay_id");
		// 请求订单号成功
		if (StringUtils.isNotBlank(prepay_id)) {
			log.info("订单请求成功！");
			try {
				log.info("插入数据库！");
				payOrderService.prepayWXBefore(date, openId, out_trade_no, amount, pledge, boxId, prepay_id, password);
				long seconds = date.getTime();
				Map<String, String> paySignMap = new HashMap<>();
				paySignMap.put("appId", appid);
				paySignMap.put("timeStamp", String.valueOf(seconds));
				paySignMap.put("nonceStr", nonce_str);
				paySignMap.put("package", "prepay_id=" + prepay_id);
				paySignMap.put("signType", "MD5");
				String stringPay = DictionaryUtils.formatUrlMap(paySignMap, false, false);
				String paySign = WXMD5Util.MD5Encode(stringPay + "&key=" + KEY).toUpperCase();
				map.put("timeStamp", String.valueOf(seconds));
				map.put("nonceStr", nonce_str);
				map.put("package", "prepay_id=" + prepay_id);
				map.put("signType", "MD5");
				map.put("paySign", paySign);
				map.put("outTradeNo", out_trade_no);
			} catch (Exception e) {
				log.info("插入失败！");
				ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
				ManageCaseBox manageCaseBox1 = new ManageCaseBox();
				manageCaseBox1.setUseStatus((byte) 0);
				manageCaseBox1.setVersion(manageCaseBox.getVersion() + 1);
				ManageCaseBoxExample manageCaseBoxExample1 = new ManageCaseBoxExample();
				manageCaseBoxExample1.createCriteria().andVersionEqualTo(manageCaseBox.getVersion())
						.andIdEqualTo(manageCaseBox.getId());
				manageCaseBoxMapper.updateByExampleSelective(manageCaseBox1, manageCaseBoxExample1);

			}
		}
		return map;
	}



	/**
	 * @author liuCheng
	 * @since 2019年1月3日 上午11:40:20
	 * @param notify_url
	 * @param body
	 * @param nonce_str
	 * @param out_trade_no
	 * @param amount
	 * @param openId
	 * @param boxId
	 * @return
	 * @throws UnsupportedEncodingException
	 *             继续使用的支付
	 */
	private Map<String, Object> continueUsePayWeiXin(String notify_url, String body, String nonce_str,
			String out_trade_no, Integer amount, String openId, Integer boxId) throws UnsupportedEncodingException {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, 2);
		Date time = calendar.getTime();
		String time_expire = DateTimeHelper.formatDateTimetoString(time, "yyyyMMddHHmmss");

		Date date = new Date();
		Map<String, Object> map = new HashMap<>();
		String MCHID = WxConfig.MCH_ID;
		String KEY = WxConfig.KEY;
		String appid = WxConfig.APPID;
		Map<String, String> payMap = WxPayBeforUtil.getPayMap(appid, MCHID, nonce_str, body, out_trade_no, amount,
				openId, notify_url, time_expire);
		String stringA = DictionaryUtils.formatUrlMap(payMap, false, false);
		String stringSignTemp = stringA + "&key=" + KEY;
		String sign = Md5Util.wxXcxHash(stringSignTemp).toUpperCase();

		StringBuffer paramBuffer = WxPayBeforUtil.getPayXml(appid, MCHID, nonce_str, body, out_trade_no, amount, openId,
				notify_url, time_expire, sign);
		// 将参数 编写XML格式
		String remotePortData = getRemotePortData(WxConfig.URL,
				new String(paramBuffer.toString().getBytes(), "ISO8859-1"));

		InputStream is = new ByteArrayInputStream(remotePortData.getBytes());
		InputStreamReader isReader = new InputStreamReader(is, "utf-8");
		Map<String, String> map1 = XmlPullUtil.parse(isReader);

		// 拿到接口返回值，插入记录
		String prepay_id = map1.get("prepay_id");
		// 请求订单号成功
		if (StringUtils.isNotBlank(prepay_id)) {
			// 插入一条订单的记录
			PayOrder record = new PayOrder();
			record.setCreartTime(new Date());
			record.setOpenId(openId);
			record.setOutTradeNo(out_trade_no);
			record.setTotalFee(amount);
			record.setBoxId(boxId);
			record.setPrepayId(prepay_id);
			payOrderMapper.insertSelective(record);

			long seconds = date.getTime();
			Map<String, String> paySignMap = new HashMap<>();
			paySignMap.put("appId", appid);
			paySignMap.put("timeStamp", String.valueOf(seconds));
			paySignMap.put("nonceStr", nonce_str);
			paySignMap.put("package", "prepay_id=" + prepay_id);
			paySignMap.put("signType", "MD5");
			String stringPay = DictionaryUtils.formatUrlMap(paySignMap, false, false);
			String paySign = WXMD5Util.MD5Encode(stringPay + "&key=" + KEY).toUpperCase();
			map.put("timeStamp", String.valueOf(seconds));
			map.put("nonceStr", nonce_str);
			map.put("package", "prepay_id=" + prepay_id);
			map.put("signType", "MD5");
			map.put("paySign", paySign);
			map.put("outTradeNo", out_trade_no);
		}
		return map;
	}

	/**
	 * @author liuCheng
	 * @throws TimeoutException
	 * @throws IOException
	 * @since 2018年12月6日 下午2:06:28 不需要支付，，直接开门(取物)
	 */
	private Map<String, Object> openDoorNoPay(Integer doorNum, Date date, String caseNo, String openId,ManageCaseBox manageCaseBox) throws Exception {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMyCommonBoxByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.GET_TYPE,AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE);
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "已为您开启" + doorNum + "号箱门，请取走您的全部物品，并关好箱门");
			return returnMap;

		} catch (Exception e) {
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}
	
	/**
	 * @author 
	 * @throws TimeoutException
	 * @throws IOException
	 * @since 2020年7月4日 下午1:20 需要支付,从押金扣除
	 */
	private Map<String, Object> openDoorNeedPay(String openId,ManageCaseBox manageCaseBox,BigDecimal cost) throws Exception {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMyCommonBoxByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.GET_TYPE,AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE,cost);
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "已为您开启" + manageCaseBox.getDoorNum() + "号箱门，请取走您的全部物品，并关好箱门");
			return returnMap;
		} catch (Exception e) {
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月6日 下午3:18:08
	 * @param doorNum
	 * @param caseNo
	 * @param manageCaseBox
	 * @param openId
	 * @return
	 * @throws Exception
	 *             不用支付就可开门存物的方法
	 */
	private Map<String, Object> openDoorBySaveAndNoPay(Integer doorNum, String caseNo, ManageCaseBox manageCaseBox,
			String openId, Integer clearHour, Byte payTime, Byte payType, String password) throws Exception {
		Map<String, Object> map = new HashMap<>();

		try {
			manageCaseBoxService.openBoxCommonByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.SAVE_TYEP,
					AllConst.ACCESS_RECORD_SOURCE.WX_XCX_SOURCE, AllConst.CASE_BOX_SAVE_SOURCE.WX_XCX_SAVE_SOURCE,
					clearHour, payTime, payType, password);
			map.put("pagejump", "2");
			map.put("message", "已为您开启" + doorNum + "号门，请存入物品，并关好箱门，谢谢您的合作！！！");
		} catch (Exception e) {
			map.put("pagejump", "1");
			map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择!!!");
		}
		return map;
	}


	/**
	 * 超时时间
	 * @return 返回多少分钟后超时
	 */
	private int overTime(String caseTypePriceId){
		Integer theLenght = manageCaseTypePriceMapper.selectByPrimaryKey(caseTypePriceId).getTheLenght();
		return theLenght;
	}

	/**
	 * 将微信回调中的参数转为一个map
	 * @param request
	 * @return
	 * @throws IOException
	 */
	private Map<String, String> getStringStringMap(HttpServletRequest request) throws IOException {
		String notityXml = "";
		String inputLine = "";
		while ((inputLine = request.getReader().readLine()) != null) {
			notityXml += inputLine;
		}
		// 关闭流
		request.getReader().close();
		// 解析成Map

		InputStream iss = new ByteArrayInputStream(notityXml.getBytes());
		InputStreamReader isReader2 = new InputStreamReader(iss, "utf-8");
		return XmlPullUtil.parse(isReader2);
	}

}
